import { Sound, Test } from "../../datavo/data";
import { BaseData } from "../../datavo/DataCustom";
import { IModule } from "../common/Common";
import AppConfig from "../config/AppConfig";
import { Logger } from "../log/logger";
import Utils from "../utils/Utils";
import { DataItem } from "./DataItem";
import { rigisterTransform } from "./DataCommon";

/**
 * 静态表管理,通过此脚本获取的静态表数据都是不可变的（赋值没有用）
 */

export default class DataManage implements IModule {

    private _data: { [key: string]: DataItem<any> };

    private _registerData: { [key: string]: new () => BaseData } = {};


    initialize(): void {
        this.registerData(Sound);
        this.registerData(Test);

        rigisterTransform({
            name: "test",
            key: "priority",
            transform(value: any): any {
                return value + "_测试";
            }
        });

    }

    /**
     * 加载数据表
     * @inner
     * @param progress 进度
     */
    async loadData(progress: (value: number) => void) {

        if (!Utils.isNil(this._data)) {
            progress && progress(1);
            return;
        }

        this._data = {};

        let url = AppConfig.URL + "data/alldata.json";

        let json = await Laya.loader.fetch(url, "json", progress);

        for (const key in json) {

            if (!this._registerData[key]) {
                Logger.trace("未注册数据表:" + key);
                continue;
            }

            this._data[key] = new DataItem(this._registerData[key], json[key]);
        }
    }

    /**
     * 重新加载数据表
     * @param progress 进度
     * @returns 
     */
    async reloadData(progress?: (value: number) => void) {
        this._data = null;
        return this.loadData(progress);
    }


    getData<T extends BaseData>(c: string | (new () => T)): DataItem<T> {
        if (!this._data) {
            Logger.trace("数据未加载");
            return;
        }

        let key = typeof c === "string" ? c : c["dataName"];
        return this._data[key] as DataItem<T>;
    }


    findOneByID<T extends BaseData>(class_c: new () => T, id: number): T {
        let data = this.getData<T>(class_c);
        if (!data) return;
        return data.findOneByID(id);
    }

    findOne<T extends BaseData>(class_c: new () => T, key: keyof T, value: any): T {
        let data = this.getData<T>(class_c);
        if (!data) return;

        return data.findOne(key, value);
    }

    findOneByItem<T extends BaseData>(class_c: new () => T, item: Partial<T>, cache: boolean = false): T {
        let data = this.getData<T>(class_c);
        if (!data) return;

        return data.findOneByItem(item, cache);

    }


    findByItem<T extends BaseData>(class_c: new () => T, item: Partial<T>): T[] {
        let data = this.getData<T>(class_c);
        if (!data) return;

        return data.findByItem(item);
    }


    find<T extends BaseData>(class_c: new () => T, ...kvs: any): T[] {
        let data = this.getData(class_c);
        if (!data) return;

        return data.find(...kvs);
    }

    /**
     * 复制数据,数据内容可变
     * @param data 原数据
     * @returns 复制后的数据
     */
    copyData<T extends BaseData>(data: T): T {
        return Object.assign({}, data) as T;
    }


    private registerData(class_c: new () => BaseData) {
        this._registerData[class_c["dataName"]] = class_c;
    }

}
